package edu.scau.mis.pos.service.impl;

import edu.scau.mis.pos.entity.PosItem;
import edu.scau.mis.pos.entity.PosOrder;
import edu.scau.mis.pos.entity.PosOrderItem;
import edu.scau.mis.pos.mapper.PosItemMapper;
import edu.scau.mis.pos.mapper.PosOrderItemMapper;
import edu.scau.mis.pos.mapper.PosOrderMapper;
import edu.scau.mis.pos.service.IPosOrderItemService;
import edu.scau.mis.pos.vo.ItemVo;
import edu.scau.mis.pos.vo.OrderItemVo;
import edu.scau.mis.pos.vo.OrderVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * (OrderItem)表服务实现类
 *
 * @author makejava
 * @since 2021-11-06 21:24:53
 */
@Service("orderItemService")
public class PosOrderItemServiceImpl implements IPosOrderItemService {
    Map<String,List<PosOrderItem>> orderItemMapCache = new HashMap<>(); //orderItem缓存数据
    Map<String, OrderVo> orderMapCache = new HashMap<>(); //order缓存数据

    @Resource
    private PosOrderMapper posOrderMapper;

    @Resource
    private PosItemMapper posItemMapper;

    @Resource
    private PosOrderItemMapper posOrderItemMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param orderItemId 主键
     * @return 实例对象
     */
    @Override
    public PosOrderItem queryById(Integer orderItemId) {
        return this.posOrderItemMapper.queryById(orderItemId);
    }

    /**
     * 全查询
     *
     * @param posOrderItem 筛选条件
     * @return 查询结果
     */
    @Override
    public List<PosOrderItem> queryAll(PosOrderItem posOrderItem) {
        return posOrderItemMapper.queryAll(posOrderItem);
    }

    /**
     * 新增数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem insert(PosOrderItem posOrderItem) {
        this.posOrderItemMapper.insert(posOrderItem);
        return posOrderItem;
    }

    /**
     * 修改数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem update(PosOrderItem posOrderItem) {
        this.posOrderItemMapper.update(posOrderItem);
        return this.queryById(posOrderItem.getOrderItemId());
    }

    /**
     * 通过主键删除数据
     *
     * @param orderItemId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer orderItemId) {
        return this.posOrderItemMapper.deleteById(orderItemId) > 0;
    }

    /**
     * 获取随机生成的订单证号
     *
     * @return
     */
    @Override
    public String getOrderNo(){
        //获取当前时间
        String fotmatTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //利用java自带的uuid随机生成字符串，去掉头尾的空格和'-'字符, 保留六个字符
        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "").substring(0, 6);
        //拼接数据
        String orderNo = "so_" + fotmatTime + "_" + uuid;
        return orderNo;
    }

    /**
     * 步骤1：点击开始生成订单，开启缓存
     *
     * @param orderNo
     */
    @Override
    public boolean openMapCache(String orderNo){
        if(orderNo != null) {
            this.createOrderItemMapCache(orderNo);//开启orderItem缓存
            this.createOrderMapCache(orderNo);//开启order缓存
            return true;
        }
        return false;
    }

    /**
     * 生成缓存数据_内存存储_HashMap
     * 步骤1_依赖方法1
     *
     * @param orderNo
     * @return
     */
    private Map<String, List<PosOrderItem>> createOrderItemMapCache(String orderNo){
        List<PosOrderItem> orderBookList = new ArrayList<>();
        orderItemMapCache.put(orderNo,orderBookList);
        return orderItemMapCache;
    }

    /**
     * 生成缓存数据_内存存储_HashMap
     * 步骤1_依赖方法2
     *
     * @param orderNo
     * @return
     */
    private Map<String, OrderVo> createOrderMapCache(String orderNo){
        OrderVo orderVo = new OrderVo();
        orderMapCache.put(orderNo, orderVo);
        return orderMapCache;
    }

    /**
     * 根据获取的数量判断库存是否充足
     *
     * @param orderItemVo
     * @return 待付款产品集合
     */
    @Override
    public boolean isInventoryEnough(OrderItemVo orderItemVo){
        Integer quantity = orderItemVo.getQuantity();
        Integer inventory = posItemMapper.queryItemByItemNo(orderItemVo.getItemNo()).getInventory();
        //库存充足，返回true
        if(quantity <= inventory){
            return true;
        }
        //库存不足，返回false
        return false;
    }

    /**
     * 步骤2：下单并统计总件数和总金额
     *
     * @param orderNo 订单证号
     * @return 订单信息
     */
    public Map<String, Object> getOrderInformationByOrderNo(String orderNo){
        Map<String, Object> orderInfo = new HashMap<String, Object>();

        //统计总数量
        Integer totalQuantity = 0;
        for(PosOrderItem posOrderItem : orderItemMapCache.get(orderNo)){
            totalQuantity = totalQuantity + posOrderItem.getQuantity();
        }

        //统计总金额
        double totalAmount = 0.0;
        for(PosOrderItem posOrderItem : orderItemMapCache.get(orderNo)){
            totalAmount = totalAmount + (posOrderItem.getSalePrice() * posOrderItem.getQuantity());
        }

        orderMapCache.get(orderNo).setTotalQuantity(totalQuantity);
        orderMapCache.get(orderNo).setTotalAmount(totalAmount);
        orderMapCache.get(orderNo).setItemList(getEnterItemList(orderNo));

        orderInfo.put("orderInfo", orderMapCache.get(orderNo));

        return orderInfo;
    }

    /**
     * 步骤2_依赖方法1：添加产品到待付款列表
     *
     * @param orderItemVo
     * @return
     */
    @Override
    public List<ItemVo> enterLineOrderItem(OrderItemVo orderItemVo){
        //获取orderNo
        String orderNo = orderItemVo.getOrderNo();
        //获取itemNo
        String itemNo = orderItemVo.getItemNo();
        //获取quantity
        Integer quantity = orderItemVo.getQuantity();

        //根据itemNo查询产品对象
        PosItem posItem = posItemMapper.queryItemByItemNo(itemNo);

        //如果产品证号相同，则将数量累加
        List<PosOrderItem> orderItemList = orderItemMapCache.get(orderNo);
        for(PosOrderItem orderItem : orderItemList){
            String oldItemNo = posItemMapper.queryItemByItemId(orderItem.getItemId()).getItemNo();
            if(oldItemNo.equals(itemNo)){
                orderItem.setQuantity(quantity + orderItem.getQuantity());
                return getEnterItemList(orderNo);
            }
        }

        PosOrderItem posOrderItem = new PosOrderItem();
        /*
            使用random函数给主键随机赋值
            Math.random生成种子，作为参数传给Random(long seed)生成随机数，确保主键的唯一性
         */
        posOrderItem.setOrderItemId(new Random((long)(Math.random() * 100)).nextInt());
        posOrderItem.setOrderId(new Random((long)(Math.random() * 100)).nextInt());
        posOrderItem.setItemId(posItem.getItemId());
        posOrderItem.setSalePrice(posItem.getPrice());
        posOrderItem.setQuantity(quantity);

        orderItemList = orderItemMapCache.get(orderNo);
        orderItemList.add(posOrderItem);
        orderItemMapCache.put(orderNo, orderItemList);
        return this.getEnterItemList(orderNo);
    }

    /**
     * 步骤2_依赖方法2：根据orderNo从缓存加载itemNo，得到待付款产品集合
     *
     * @param orderNo 订单证号
     * @return 待付款产品集合
     */
    List<ItemVo> getEnterItemList(String orderNo){
        List<ItemVo> enterItemList = new ArrayList<>();
        List<PosOrderItem> orderItemList = orderItemMapCache.get(orderNo);
        for(PosOrderItem orderItem : orderItemList){
            ItemVo itemVo = new ItemVo();
            itemVo.setItemNo(posItemMapper.queryById(orderItem.getItemId()).getItemNo());
            itemVo.setItemName(posItemMapper.queryById(orderItem.getItemId()).getItemName());
            itemVo.setPrice(posItemMapper.queryById(orderItem.getItemId()).getPrice());
            itemVo.setQuantity(orderItem.getQuantity());
            itemVo.setAmount(itemVo.getPrice() * itemVo.getQuantity());
            enterItemList.add(itemVo);
        }
        return enterItemList;
    }

    /**
     * 获取先前的订单信息，用于库存不足无法下单时
     *
     * @return
     */
    @Override
    public OrderVo getPreviousOrderInfo(String orderNo){
        OrderVo orderVo = new OrderVo();
        orderVo.setItemList(getEnterItemList(orderNo));
        orderVo.setTotalQuantity(orderMapCache.get(orderNo).getTotalQuantity());
        orderVo.setTotalAmount(orderMapCache.get(orderNo).getTotalAmount());
        return orderVo;
    }

    /**
     * 步骤3：确认下单
     *
     * @param orderNo 订单证号
     * @return 操作结果
     */
    @Override
    public boolean ConfirmPayItem(String orderNo){
        PosOrder posOrder = new PosOrder();
        posOrder.setOrderId(orderItemMapCache.get(orderNo).get(0).getOrderId());
        posOrder.setOrderNo(orderNo);
        posOrder.setSaleDatetime(new Date());
        posOrder.setTotalAmount(orderMapCache.get(orderNo).getTotalAmount());
        posOrder.setTotalQuantity(orderMapCache.get(orderNo).getTotalQuantity());
        //插入到订单表, 如果插入失败则返回false
        if(posOrderMapper.insert(posOrder) < 0){
            return false;
        }

        for(PosOrderItem posOrderItem : orderItemMapCache.get(orderNo)){
            //插入到订单明细表, 如果插入失败则回滚删除之前插入的数据，返回false
            if(posOrderItemMapper.insert(posOrderItem) < 0){
                posOrderItemMapper.rollbackByorderId(posOrderItem.getOrderId());
                return false;
            }
            //更新库存
            String itemNo = posItemMapper.queryItemByItemId(posOrderItem.getItemId()).getItemNo();
            Integer inventory = posItemMapper.queryItemByItemNo(itemNo).getInventory() - posOrderItem.getQuantity();
            if(posItemMapper.updateInventory(posOrderItem.getItemId(), inventory) < 0){
                return false;
            }
        }
        return true;
    }


}
